//==============================================================================
//
// Title:       USB6501
// Purpose:     .
//
// Created on:  2011-9-16 at 18:54:39 by luh.
// Copyright:   dafda. All Rights Reserved.
//
//==============================================================================
//==============================================================================
// Include files
#include "RFBB.h"
#include <ansi_c.h>
#include <cvirte.h>
#include <userint.h>
#include <ctype.h>
#include <stdio.h>
#include <NIDAQmx.h>
#include <DAQmxIOctrl.h>

#include "USB6501.h"
//==============================================================================
// Constants
#define DAQmxErrChk(functionCall) if( DAQmxFailed(error=(functionCall)) ) goto Error;
//==============================================================================
// Types

//==============================================================================
// Static global variables

//==============================================================================
// Static functions
#if 0
int main (int argc, char *argv[])
{
    _DAQMX_WRITE_LINES_CMD lvDaqmxWriteLinesCmd = {"write to port0 lines","Dev1/port0/line0:7",{0,1,0,1,0,1,0,1}};     
    _DAQMX_WRITE_PORT_CMD lvDaqmxWritePortCmd = {"write to port0","Dev1/port0",0x55};
    _DAQMX_WRITE_ONE_LINE_CMD lvDaqmxWriteOneLineCmd = {"write to port0 linex","Dev1/port0/line2",0x00};
    _DAQMX_READ_LINES_CMD lvDaqmxReadLinesCmd = {"Read from port1 lines","Dev1/port1/line0:7",{0}};
    _DAQMX_READ_PORT_CMD  lvDaqmxReadPortcmd = {"Read from port1","Dev1/port1",0x00};
    _DAQMX_READ_ONE_LINE_CMD lvDaqmxReadOneLineCmd = {"Read from port1 linex","Dev1/port1/line1",0};

    
    if (InitCVIRTE (0, argv, 0) == 0)
    {
		return -1;    /* out of memory */
    }
    
	/**************************************USB 6501 TEST DEMO**********************************************/

    //write to all lines bit0-----bit7 
    //              char data[0]--data[7]
	USBWriteDigToAllLines(lvDaqmxWriteLinesCmd.ucTashName,lvDaqmxWriteLinesCmd.ucDevportlines,lvDaqmxWriteLinesCmd.uWriteData);
    
    //write to port  bit7-----bit0 
    // uWriteData  bit7-----bit0
    USBWriteDigToPort(lvDaqmxWritePortCmd.ucTashName,lvDaqmxWritePortCmd.ucDevport,lvDaqmxWritePortCmd.uiWriteData);

    //write to port  linex 
    // uWriteData   only bit0
    USBWriteDigToOneLine(lvDaqmxWriteOneLineCmd.ucTashName,lvDaqmxWriteOneLineCmd.ucDevportline,lvDaqmxWriteOneLineCmd.uWriteData);

    //Read from all lines bit0-----bit7 
    //              char data[0]--data[7]
    USBReadDigFromAllLines(lvDaqmxReadLinesCmd.ucTashName,lvDaqmxReadLinesCmd.ucDevportlines,lvDaqmxReadLinesCmd.uReadData);

    //Read from all lines bit0-----bit7 
    //             uInt32     bit0-----bit7
    USBReadDigFromPort(lvDaqmxReadPortcmd.ucTashName,lvDaqmxReadPortcmd.ucDevport,&lvDaqmxReadPortcmd.uiReadata);

    //read from port  linex 
    // uReadData   only bit0
    USBReadDigFromOneLine(lvDaqmxReadOneLineCmd.ucTashName,lvDaqmxReadOneLineCmd.ucDevportline, lvDaqmxReadOneLineCmd.uReadata);

    return 0;
}
#endif

#if(ON_OFF != SIMU_VERS)
//**************************************************************************
//* Steps:
//*    1. Create a task.
//*    2. Create a Digital Output channel. Use one channel for all
//*       lines.
//*    3. Call the Start function to start the task.
//*    4. Write the digital Boolean array data. This write function
//*       writes a single sample of digital data on demand, so no
//*       timeout is necessary.
//*    5. Call the Clear Task function to clear the Task.
//*    6. Display an error if any.
//************************************************************************** 
int USBWriteDigToPort(const char *ptrTashName,const char *ptrDevport, uInt32 uDataToPort)
{
    
	TaskHandle  taskHandle=0;
    char        errBuff[2048]={'\0'};
    
    int         error=0;
    int32		written;


    if(NULL == ptrDevport)
    {
        return 1;
    }
    
	/*********************************************/
	// DAQmx Configure Code
	/*********************************************/
	DAQmxErrChk (DAQmxCreateTask(ptrTashName,&taskHandle));
	DAQmxErrChk (DAQmxCreateDOChan(taskHandle,ptrDevport,ptrTashName,DAQmx_Val_ChanForAllLines));

	/*********************************************/
	// DAQmx Start Code
	/*********************************************/
	DAQmxErrChk (DAQmxStartTask(taskHandle));

	/*********************************************/
	// DAQmx Write Code
	/*********************************************/
	DAQmxErrChk (DAQmxWriteDigitalU32(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,&uDataToPort,&written,NULL)); 

Error:

	if(DAQmxFailed(error))
    {   
		DAQmxGetExtendedErrorInfo(errBuff,2048);
    }
    
	if( taskHandle!=0 )
    {
		/*********************************************/
		// DAQmx Stop Code
		/*********************************************/
		DAQmxStopTask(taskHandle);
		DAQmxClearTask(taskHandle);
	}
	if(DAQmxFailed(error))
    {   
		MessagePopup("DAQmx Error",errBuff);
    }
    
	return error;
}

//**************************************************************************
//* Steps:
//*    1. Create a task.
//*    2. Create a Digital Output channel. Use one channel for all
//*       lines.
//*    3. Call the Start function to start the task.
//*    4. Write the digital Boolean array data. This write function
//*       writes a single sample of digital data on demand, so no
//*       timeout is necessary.
//*    5. Call the Clear Task function to clear the Task.
//*    6. Display an error if any.
//************************************************************************** 
int USBWriteDigToAllLines(const char *ptrTashName,const char *ptrDevportlines, uInt8 *ptrucDataToLine)
{
    
	TaskHandle  taskHandle = 0;
    char        errBuff[2048] = {'\0'};
    
    int         error = 0;
    //uInt8       ucDataToLine[]


    if(NULL == ptrDevportlines)
    {
        return 1;
    }
    
	/*********************************************/
	// DAQmx Configure Code
	/*********************************************/
	DAQmxErrChk (DAQmxCreateTask(ptrTashName,&taskHandle));
	DAQmxErrChk (DAQmxCreateDOChan(taskHandle,ptrDevportlines,ptrTashName,DAQmx_Val_ChanForAllLines));

	/*********************************************/
	// DAQmx Start Code
	/*********************************************/
	DAQmxErrChk (DAQmxStartTask(taskHandle));

	/*********************************************/
	// DAQmx Read Code
	/*********************************************/
	DAQmxErrChk (DAQmxWriteDigitalLines(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,ptrucDataToLine,NULL,NULL)); 

Error:

	if(DAQmxFailed(error))
    {   
		DAQmxGetExtendedErrorInfo(errBuff,2048);
    }
    
	if( taskHandle!=0 )
    {
		/*********************************************/
		// DAQmx Stop Code
		/*********************************************/
		DAQmxStopTask(taskHandle);
		DAQmxClearTask(taskHandle);
	}
	if(DAQmxFailed(error))
    {   
		MessagePopup("DAQmx Error",errBuff);
    }
    
	return error;
}

//**************************************************************************
//* Steps:
//*    1. Create a task.
//*    2. Create a Digital Output channel. Use one channel for one
//*       line.
//*    3. Call the Start function to start the task.
//*    4. Write the digital Boolean array data. This write function
//*       writes a single sample of digital data on demand, so no
//*       timeout is necessary.
//*    5. Call the Clear Task function to clear the Task.
//*    6. Display an error if any.
//************************************************************************** 
int USBWriteDigToOneLine(const char *ptrTashName,const char *ptrDevportline, uInt8 ucDataToLine)
{
    
	TaskHandle  taskHandle=0;
    char        errBuff[2048]={'\0'};
    
    int         error=0; 

    if(NULL == ptrDevportline)
    {
        return 1;
    }
    
	/*********************************************/
	// DAQmx Configure Code
	/*********************************************/
	DAQmxErrChk (DAQmxCreateTask(ptrTashName,&taskHandle));
	DAQmxErrChk (DAQmxCreateDOChan(taskHandle,ptrDevportline,ptrTashName,DAQmx_Val_ChanPerLine));

	/*********************************************/
	// DAQmx Start Code
	/*********************************************/
	DAQmxErrChk (DAQmxStartTask(taskHandle));

	/*********************************************/
	// DAQmx Write Code
	/*********************************************/
	DAQmxErrChk (DAQmxWriteDigitalLines(taskHandle,1,1,10.0,DAQmx_Val_GroupByChannel,&ucDataToLine,NULL,NULL)); 

Error:

	if(DAQmxFailed(error))
    {   
		DAQmxGetExtendedErrorInfo(errBuff,2048);
    }
    
	if( taskHandle!=0 )
    {
		/*********************************************/
		// DAQmx Stop Code
		/*********************************************/
		DAQmxStopTask(taskHandle);
		DAQmxClearTask(taskHandle);
	}
    
	if(DAQmxFailed(error))
    {   
		MessagePopup("DAQmx Error",errBuff);
    }
    
	return error;
}

int USBReadDigFromPort(const char *ptrTashName,const char *ptrDevportline, uInt32 *ptrDataFromLine)
{
    
	TaskHandle  taskHandle = 0;
    char        errBuff[2048]={'\0'};
    
    int         error=0;
    int32		read; 

    if(NULL == ptrDevportline)
    {
        return 1;
    }
    
	/*********************************************/
	// DAQmx Configure Code
	/*********************************************/
	DAQmxErrChk (DAQmxCreateTask(ptrTashName,&taskHandle));
	DAQmxErrChk (DAQmxCreateDIChan(taskHandle,ptrDevportline,ptrTashName,DAQmx_Val_ChanForAllLines));    

	/*********************************************/
	// DAQmx Start Code
	/*********************************************/
	DAQmxErrChk (DAQmxStartTask(taskHandle));

	/*********************************************/
	// DAQmx Read Code
	/*********************************************/
	DAQmxErrChk (DAQmxReadDigitalU32(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,ptrDataFromLine,1,&read,NULL));                  

Error:

	if(DAQmxFailed(error))
    {   
		DAQmxGetExtendedErrorInfo(errBuff,2048);
    }
    
	if( taskHandle!=0 )
    {
		/*********************************************/
		// DAQmx Stop Code
		/*********************************************/
		DAQmxStopTask(taskHandle);
		DAQmxClearTask(taskHandle);
	}
    
	if(DAQmxFailed(error))
    {   
		MessagePopup("DAQmx Error",errBuff);
    }
    
	return error;
}

int USBReadDigFromAllLines(const char *ptrTashName,const char *ptrDevportline, uInt8 *ptrDataFromLine)
{
    
	TaskHandle  taskHandle=0;
    char        errBuff[2048]={'\0'};
    
    int         error=0;
    int32		read;
    int32       bytesPerSamp;

    if(NULL == ptrDevportline)
    {
        return 1;
    }
    
	/*********************************************/
	// DAQmx Configure Code
	/*********************************************/
	DAQmxErrChk (DAQmxCreateTask(ptrTashName,&taskHandle));
	DAQmxErrChk (DAQmxCreateDIChan(taskHandle,ptrDevportline,ptrTashName,DAQmx_Val_ChanForAllLines));

	/*********************************************/
	// DAQmx Start Code
	/*********************************************/
	DAQmxErrChk (DAQmxStartTask(taskHandle));

	/*********************************************/
	// DAQmx Read Code
	/*********************************************/
	DAQmxErrChk (DAQmxReadDigitalLines(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,ptrDataFromLine,100,&read,&bytesPerSamp,NULL));
Error:

	if(DAQmxFailed(error))
    {   
		DAQmxGetExtendedErrorInfo(errBuff,2048);
    }
    
	if( taskHandle!=0 )
    {
		/*********************************************/
		// DAQmx Stop Code
		/*********************************************/
		DAQmxStopTask(taskHandle);
		DAQmxClearTask(taskHandle);
	}
    
	if(DAQmxFailed(error))
    {   
		MessagePopup("DAQmx Error",errBuff);
    }
    
	return error;
}

int USBReadDigFromOneLine(const char *ptrTashName,const char *ptrDevportline, uInt8 *ptrDataFromLine)
{
    
	TaskHandle  taskHandle=0;
    char        errBuff[2048]={'\0'};
    
    int         error=0;
    int32		read;
    int32       bytesPerSamp;

    if(NULL == ptrDevportline)
    {
        return 1;
    }
    
	/*********************************************/
	// DAQmx Configure Code
	/*********************************************/
	DAQmxErrChk (DAQmxCreateTask(ptrTashName,&taskHandle));
	DAQmxErrChk (DAQmxCreateDIChan(taskHandle,ptrDevportline,ptrTashName,DAQmx_Val_ChanPerLine));

	/*********************************************/
	// DAQmx Start Code
	/*********************************************/
	DAQmxErrChk (DAQmxStartTask(taskHandle));

	/*********************************************/
	// DAQmx Read Code
	/*********************************************/
	DAQmxErrChk (DAQmxReadDigitalLines(taskHandle,1,10.0,DAQmx_Val_GroupByChannel,ptrDataFromLine,100,&read,&bytesPerSamp,NULL)); 

Error:

	if(DAQmxFailed(error))
    {   
		DAQmxGetExtendedErrorInfo(errBuff,2048);
    }
    
	if( taskHandle!=0 )
    {
		/*********************************************/
		// DAQmx Stop Code
		/*********************************************/
		DAQmxStopTask(taskHandle);
		DAQmxClearTask(taskHandle);
	}
    
	if(DAQmxFailed(error))
    {   
		MessagePopup("DAQmx Error",errBuff);
    }
    
	return error;
}

// -----------------------------------------------------------------------
// Function:   InitialiseDio   
//             
//
int InitDIO(void)
{
   int iRet = 0;
   int error = 0;          // required for tsErrChk
   ErrMsg errMsg = {'\0'}; // required for tsErrChk
   
   unsigned int size = 0;
   unsigned char szDeviceName[255] = {'\0'}; 
   char szLogMsg[BUF_SIZE_SMALL] = {'\0'};
   
   // USB DIO initialisations
   sprintf( szLogMsg, "Init NIDAQmx USB-DIO..." );
   ErrChk(EELog_INEventLogLogEvent (g_hEventLog, NULL, szLogMsg));

   error = RegReadString (REGKEY_HKLM, "SOFTWARE\\NSN\\SWIFT\\Instruments\\DIO", 
         "DeviceName", szDeviceName, sizeof(szDeviceName), &size);
   if( error )
   {
      sprintf(errMsg, "DIO DeviceName error!");
      goto Error;
   }

   DAQmxResetDevice (szDeviceName);
   Delay(2.0);

   //error = InitUsbDio(szDeviceName);
   
Error:
   // FREE RESOURCES
   
    if ( error != 0 )
    {
        ErrChk(EELog_INEventLogLogEvent ( g_hEventLog, NULL, errMsg ));
        iRet = -1;
    }
   
    return iRet;
}

#else
int USBWriteDigToPort(const char *ptrTashName,const char *ptrDevport, uInt32 uDataToPort)
{
	return 0;
}

int USBWriteDigToAllLines(const char *ptrTashName,const char *ptrDevportlines, uInt8 *ptrucDataToLine)
{
    return 0;
}

int USBWriteDigToOneLine(const char *ptrTashName,const char *ptrDevportline, uInt8 ucDataToLine)
{
    return 0;
}

int USBReadDigFromPort(const char *ptrTashName,const char *ptrDevportline, uInt32 *ptrDataFromLine)
{
    return 0;
}

int USBReadDigFromAllLines(const char *ptrTashName,const char *ptrDevportline, uInt8 *ptrDataFromLine)
{
    return 0;
}

int USBReadDigFromOneLine(const char *ptrTashName,const char *ptrDevportline, uInt8 *ptrDataFromLine)
{
    return 0;
}

#endif
